<?php
abstract class HackerU_Db_Table implements HackerU_Interface_Crud
{
	/**
	 * 
	 * table name
	 * @var string
	 */
	protected $name;
	
	/**
	 * 
	 * db connection
	 * @var Hacker_Db_Conn instance
	 */
	protected $conn;
	
	/**
	 * 
	 * the constructor
	 */
	public function __construct()
	{
		$this->initTableName();
		$this->conn = HackerU_Db_Conn::getInstance()->getConn();
	}
	
	/**
	 * 
	 * set the db table name
	 */
	protected function initTableName()
	{
		//return the className
		$className = get_class($this);
		//set class name to array
		$classNameArr = explode('_', $className);
		//set the table name
		$this->name = strtolower($classNameArr[count($classNameArr) - 1]);
	}
	
	public function escape($s)
	{
		$s = str_replace("'","''",$s);
		$s = str_replace("\0","\\0",$s);
		return $s;
	}
	
	public function insert(array $data)
	{
		$columns = $values = '';
		foreach ($data as $col => $val){
			if($columns){
				$columns .= ',';
			}
			$columns .= $col;
			if($values){
				$values .= ',';
			}
			$values .= "'".$this->escape($val)."'";
		}
		
		$sql = " INSERT INTO $this->name($columns) VALUES($values) ";
		
		$this->conn->query($sql);
		return $this->conn->insert_id;
	}
	
	public function fetchByQuery($sql)
	{
		$rows = array();
		$result = $this->conn->query($sql);
		if($result){
			while ($row = $result->fetch_object()) {
				$rows[] = $row;
			}
			$result->close();
		}
		return $rows;
	}
	
	public function update(array $update, array $cond)
	{
		$set = $where = '';
		foreach ($update as $col => $val){
			if($set){
				$set .= ',';
			}
			$set .= $col." = '". $this->escape($val)."'";
		}
		foreach ($cond as $col => $val){
			$val = $this->escape($val);
			if($where){
				$where .= ' AND ';
			}
			$where .= " $col = '$val' ";
		}
		$sql = " UPDATE  $this->name SET $set WHERE $where ";
		return $this->conn->query($sql);
	}
	
	/**
	 * 
	 * delete records
	 * @param assoc array  $cond(key == column name , value) 
	 */
	public function delete(array $cond)
	{
		$where = '';
		foreach ($cond as $col => $val){
			$val = $this->escape($val);
			if($where){
				$where .= ' AND ';
			}
			$where .= " $col = '$val' ";
		}
		$sql = " DELETE  FROM $this->name WHERE $where ";
		return $this->conn->query($sql);
	}
	
	//SELECT id,firsName FROM `adresses`
	public function select(array $what = array(), array $cond = array())
	{
		$rows = array();
		$select = $where = '';
		foreach ($what as $col){
			if($select){
				$select .= ',';
			}
			$select .= $col;
		}
		if(!$select){
			$select = '*';
		}
		foreach ($cond as $col => $val){
			$val = $this->escape($val);
			if($where){
				$where .= ' AND ';
			}
			$where .= " $col = '$val' ";
		}
		if($where){
			$where = " WHERE $where ";
		}
		
		$sql = " SELECT  $select FROM $this->name $where ";
		//var_dump($sql);die;
		$result = $this->conn->query($sql);
		if($result){
			while ($row = $result->fetch_object()) {
				$rows[] = $row;
			}
			$result->close();
		}
		return $rows;
	}
	
	public function fetchOne(array $what = array(), array $cond = array())
	{
		$ret = $this->select($what, $cond);
		$ret = array_shift($ret);
		return $ret;
	}
	
	public function fetchAll()
	{
		return $this->select();
	}
	
	/**
	 * 
	 * save user data
	 * @param array $data assoc(key (colName) => val)
	 */
	public function save(array $data)
	{
		if(!isset($data['id']) || !$data['id']){
			return $this->insert($data);
		}
		$cond = array('id' => (int)$data['id']);
		unset($data['id']);
		return $this->update($data, $cond);
	}
}
